#ifndef LOGGER_H
#define LOGGER_H

#include <string>
#include <array>

#define EASE_DEBUG(...) logger::debugLog(logger::MessageLogContext(__FILE__, __FUNCTION__, __LINE__), __VA_ARGS__)
#define EASE_INFO(...) logger::infoLog(logger::MessageLogContext(__FILE__, __FUNCTION__, __LINE__), __VA_ARGS__)
#define EASE_WARN(...) logger::warningLog(logger::MessageLogContext(__FILE__, __FUNCTION__, __LINE__), __VA_ARGS__)
#define EASE_ERROR(...) logger::errorLog(logger::MessageLogContext(__FILE__, __FUNCTION__, __LINE__), __VA_ARGS__)
#define EASE_FATAL(...) logger::fatalLog(logger::MessageLogContext(__FILE__, __FUNCTION__, __LINE__), __VA_ARGS__)

namespace logger
{
/**
 * @brief:  日志等级
 */
enum LogLevel
{
    LEVEL_DEBUG = 0,  //debug
    LEVEL_INFO,       //info
    LEVEL_WARNING,    //warning
    LEVEL_ERROR,      //error
    LEVEL_FATAL       //fatal
};

class MessageLogContext
{
public:
    MessageLogContext(const char *file, const char *function, int line)
        : file(file), function(function), line(line)
    {}

    const char *file;
    const char *function;
    int line;
};

typedef void(*MessageOutput)(LogLevel logLevel, const MessageLogContext &context, const std::string &msg);

/**
 * @brief:  注册日志回调
 * @author: sherlock_lht
 */
void installMessageHandler(MessageOutput messageOutput);

void debugLog(const MessageLogContext &context, const char *fmt, ...);
void infoLog(const MessageLogContext &context, const char *fmt, ...);
void warningLog(const MessageLogContext &context, const char *fmt, ...);
void errorLog(const MessageLogContext &context, const char *fmt, ...);
void fatalLog(const MessageLogContext &context, const char *fmt, ...);

}

#endif //LOGGER_H
